package sk.naive.talker;

import sk.naive.talker.util.Utils;

import java.io.*;
import java.util.*;

/**
 * Configuration represents configuration data during runtime.
 *
 * @author <a href="mailto:virgo@naive.deepblue.sk">Richard "Virgo" Richter</a>
 * @version $Revision: 1.4 $ $Date: 2004/12/23 23:23:08 $
 */
public class Configuration {
	private Map<String,Set<String>> sectionProps;
	private Map<String,String> propValues;

	public Configuration(String filename) throws TalkerConfigurationException {
		try {
			init(new BufferedReader(new FileReader(filename)));
		} catch (FileNotFoundException e) {
			throw new TalkerConfigurationException("Configuration file: '" + filename + "' not found.", e);
		}
	}

	public Configuration(InputStream stream) {
		init(new InputStreamReader(stream));
	}


	private void init(Reader reader) {
		sectionProps = new HashMap<String,Set<String>>();
		propValues = new LinkedHashMap<String,String>();

		Set<String> sectionSet = getSectionSet("");
		LineNumberReader lnr = null;
		try {
			lnr = new LineNumberReader(reader);
			while (true) {
				String line = lnr.readLine();
				if (line == null) {
					break;
				}
				if (line.length() == 0) {
					continue;
				}
				if (line.charAt(0) == '#') {
					continue;
				}
				if (line.charAt(0) == '[' && line.charAt(line.length() - 1) == ']') {
					sectionSet = getSectionSet(line.substring(1, line.length() - 1));
					continue;
				}
				String[] sa = line.split(" *= *", 2);
				String key = sa[0];
				String value = null;
				if (sa.length > 1) {
					value = sa[1];
				}
				propValues.put(key, value);
				sectionSet.add(key);
			}
		} catch (IOException e) {
			Utils.unexpectedExceptionWarning(e);
		} finally {
			try {
				if (lnr != null) {
					lnr.close();
				}
			} catch (IOException e) {
				Utils.unexpectedExceptionWarning(e);
			}
		}
	}

	private Set<String> getSectionSet(String sectionName) {
		Set<String> sectionSet = sectionProps.get(sectionName);
		if (sectionSet == null) {
			sectionSet = new LinkedHashSet<String>();
			sectionProps.put(sectionName, sectionSet);
		}
		return sectionSet;
	}

	public Collection<String> getSectionNames() {
		return Collections.unmodifiableCollection(sectionProps.keySet());
	}

	public Set<String> getSectionProps(String name) {
		return Collections.unmodifiableSet(sectionProps.get(name));
	}

	public String get(String prop) {
		return propValues.get(prop);
	}

	public String get(String prop, String defaultValue) {
		String val = propValues.get(prop);
		if (val == null) {
			val = defaultValue;
		}
		return val;
	}

	public int getInt(String prop, int defaultValue) {
		String val = propValues.get(prop);
		if (val == null) {
			return defaultValue;
		}
		return Integer.parseInt(val);
	}

	public long getLong(String prop, long defaultValue) {
		String val = propValues.get(prop);
		if (val == null) {
			return defaultValue;
		}
		return Long.parseLong(val);
	}
}
